﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;

namespace Teigha.Core
{
	public class OdBoolArray : IDisposable, IList<bool>, ICollection<bool>, IEnumerable<bool>, IEnumerable
	{
		[EditorBrowsable(EditorBrowsableState.Never)]
		public OdBoolArray(IntPtr cPtr, bool cMemoryOwn)
		{
			this.swigCMemOwn = cMemoryOwn;
			this.swigCPtr = new HandleRef(this, cPtr);
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static HandleRef getCPtr(OdBoolArray obj)
		{
			if (obj != null)
			{
				return obj.swigCPtr;
			}
			return new HandleRef(null, IntPtr.Zero);
		}

		~OdBoolArray()
		{
			this.Dispose();
		}

		public virtual void Dispose()
		{
			if (this.swigCPtr.Handle != IntPtr.Zero)
			{
				if (this.swigCMemOwn)
				{
					lock (this.locker)
					{
						if (this.swigCPtr.Handle != IntPtr.Zero && this.swigCMemOwn)
						{
							this.swigCMemOwn = false;
							GlobalsPINVOKE.delete_OdBoolArray(this.swigCPtr);
						}
					}
					this.swigCMemOwn = false;
				}
				this.swigCPtr = new HandleRef(null, IntPtr.Zero);
			}
			GC.SuppressFinalize(this);
		}

		public OdBoolArray(ICollection c) : this()
		{
			if (c == null)
			{
				throw new System.ArgumentNullException("c");
			}
			foreach (object obj in c)
			{
				bool x = (bool)obj;
				this.Add(x);
			}
		}

		public OdBoolArray() : this(GlobalsPINVOKE.new_OdBoolArray__SWIG_0(), MemoryManager.GetMemoryManager().GetCurrentTransaction() == null)
		{
			MemoryTransaction currentTransaction = MemoryManager.GetMemoryManager().GetCurrentTransaction();
			if (currentTransaction != null)
			{
				currentTransaction.AddObject(new OdBoolArray(this.swigCPtr.Handle, true));
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public OdBoolArray(OdBoolArray other) : this(GlobalsPINVOKE.new_OdBoolArray__SWIG_1(OdBoolArray.getCPtr(other)), MemoryManager.GetMemoryManager().GetCurrentTransaction() == null)
		{
			MemoryTransaction currentTransaction = MemoryManager.GetMemoryManager().GetCurrentTransaction();
			if (currentTransaction != null)
			{
				currentTransaction.AddObject(new OdBoolArray(this.swigCPtr.Handle, true));
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public OdBoolArray(int capacity) : this(GlobalsPINVOKE.new_OdBoolArray__SWIG_2(capacity), MemoryManager.GetMemoryManager().GetCurrentTransaction() == null)
		{
			MemoryTransaction currentTransaction = MemoryManager.GetMemoryManager().GetCurrentTransaction();
			if (currentTransaction != null)
			{
				currentTransaction.AddObject(new OdBoolArray(this.swigCPtr.Handle, true));
			}
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public bool IsFixedSize
		{
			get
			{
				return false;
			}
		}

		public bool IsReadOnly
		{
			get
			{
				return false;
			}
		}

		public bool this[int index]
		{
			get
			{
				return this.getitem(index);
			}
			set
			{
				this.setitem(index, value);
			}
		}

		public int Capacity
		{
			get
			{
				return (int)this.capacity();
			}
			set
			{
				if ((long)value < (long)((ulong)this.size()))
				{
					throw new ArgumentOutOfRangeException("Capacity");
				}
				this.reserve((uint)value);
			}
		}

		public int Count
		{
			get
			{
				return (int)this.size();
			}
		}

		public bool IsSynchronized
		{
			get
			{
				return false;
			}
		}

		public void CopyTo(bool[] array)
		{
			this.CopyTo(0, array, 0, this.Count);
		}

		public void CopyTo(bool[] array, int arrayIndex)
		{
			this.CopyTo(0, array, arrayIndex, this.Count);
		}

		public void CopyTo(int index, bool[] array, int arrayIndex, int count)
		{
			if (array == null)
			{
				throw new System.ArgumentNullException("array");
			}
			if (index < 0)
			{
				throw new ArgumentOutOfRangeException("index", "Value is less than zero");
			}
			if (arrayIndex < 0)
			{
				throw new ArgumentOutOfRangeException("arrayIndex", "Value is less than zero");
			}
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count", "Value is less than zero");
			}
			if (array.Rank > 1)
			{
				throw new ArgumentException("Multi dimensional array.", "array");
			}
			if (index + count > this.Count || arrayIndex + count > array.Length)
			{
				throw new ArgumentException("Number of elements to copy is too large.");
			}
			for (int i = 0; i < count; i++)
			{
				array.SetValue(this.getitemcopy(index + i), arrayIndex + i);
			}
		}

		IEnumerator<bool> IEnumerable<bool>.GetEnumerator()
		{
			return new OdBoolArray.OdBoolArrayEnumerator(this);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return new OdBoolArray.OdBoolArrayEnumerator(this);
		}

		public OdBoolArray.OdBoolArrayEnumerator GetEnumerator()
		{
			return new OdBoolArray.OdBoolArrayEnumerator(this);
		}

		public void Clear()
		{
			GlobalsPINVOKE.OdBoolArray_Clear(this.swigCPtr);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public void Add(bool x)
		{
			GlobalsPINVOKE.OdBoolArray_Add(this.swigCPtr, x);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		private uint size()
		{
			uint result = GlobalsPINVOKE.OdBoolArray_size(this.swigCPtr);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		private uint capacity()
		{
			uint result = GlobalsPINVOKE.OdBoolArray_capacity(this.swigCPtr);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		private void reserve(uint n)
		{
			GlobalsPINVOKE.OdBoolArray_reserve(this.swigCPtr, n);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public void resize(uint logicalLength)
		{
			GlobalsPINVOKE.OdBoolArray_resize(this.swigCPtr, logicalLength);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		private bool getitemcopy(int index)
		{
			bool result = GlobalsPINVOKE.OdBoolArray_getitemcopy(this.swigCPtr, index);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		private bool getitem(int index)
		{
			bool result = GlobalsPINVOKE.OdBoolArray_getitem(this.swigCPtr, index);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		private void setitem(int index, bool val)
		{
			GlobalsPINVOKE.OdBoolArray_setitem(this.swigCPtr, index, val);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public void AddRange(OdBoolArray values)
		{
			GlobalsPINVOKE.OdBoolArray_AddRange(this.swigCPtr, OdBoolArray.getCPtr(values));
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public OdBoolArray GetRange(int index, int count)
		{
			IntPtr intPtr = GlobalsPINVOKE.OdBoolArray_GetRange(this.swigCPtr, index, count);
			OdBoolArray result = (intPtr == IntPtr.Zero) ? null : new OdBoolArray(intPtr, false);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public void Insert(int index, bool x)
		{
			GlobalsPINVOKE.OdBoolArray_Insert(this.swigCPtr, index, x);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public void InsertRange(int index, OdBoolArray values)
		{
			GlobalsPINVOKE.OdBoolArray_InsertRange(this.swigCPtr, index, OdBoolArray.getCPtr(values));
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public void RemoveAt(int index)
		{
			GlobalsPINVOKE.OdBoolArray_RemoveAt(this.swigCPtr, index);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public void RemoveRange(int index, int count)
		{
			GlobalsPINVOKE.OdBoolArray_RemoveRange(this.swigCPtr, index, count);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public static OdBoolArray Repeat(bool value, int count)
		{
			IntPtr intPtr = GlobalsPINVOKE.OdBoolArray_Repeat(value, count);
			OdBoolArray result = (intPtr == IntPtr.Zero) ? null : new OdBoolArray(intPtr, true);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public void Reverse()
		{
			GlobalsPINVOKE.OdBoolArray_Reverse__SWIG_0(this.swigCPtr);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public void Reverse(int index, int count)
		{
			GlobalsPINVOKE.OdBoolArray_Reverse__SWIG_1(this.swigCPtr, index, count);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public void SetRange(int index, OdBoolArray values)
		{
			GlobalsPINVOKE.OdBoolArray_SetRange(this.swigCPtr, index, OdBoolArray.getCPtr(values));
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
		}

		public bool Contains(bool value)
		{
			bool result = GlobalsPINVOKE.OdBoolArray_Contains(this.swigCPtr, value);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public int IndexOf(bool value)
		{
			int result = GlobalsPINVOKE.OdBoolArray_IndexOf(this.swigCPtr, value);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public int LastIndexOf(bool value)
		{
			int result = GlobalsPINVOKE.OdBoolArray_LastIndexOf(this.swigCPtr, value);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public bool Remove(bool value)
		{
			bool result = GlobalsPINVOKE.OdBoolArray_Remove(this.swigCPtr, value);
			if (GlobalsPINVOKE.SWIGPendingException.Pending)
			{
				throw GlobalsPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		private object locker = new object();

		private HandleRef swigCPtr;

		protected bool swigCMemOwn;

		public sealed class OdBoolArrayEnumerator : IEnumerator<bool>, IDisposable, IEnumerator
		{
			public OdBoolArrayEnumerator(OdBoolArray collection)
			{
				this.collectionRef = collection;
				this.currentIndex = -1;
				this.currentObject = null;
				this.currentSize = this.collectionRef.Count;
			}

			public bool Current
			{
				get
				{
					if (this.currentIndex == -1)
					{
						throw new InvalidOperationException("Enumeration not started.");
					}
					if (this.currentIndex > this.currentSize - 1)
					{
						throw new InvalidOperationException("Enumeration finished.");
					}
					if (this.currentObject == null)
					{
						throw new InvalidOperationException("Collection modified.");
					}
					return (bool)this.currentObject;
				}
			}

			object IEnumerator.Current
			{
				get
				{
					return this.Current;
				}
			}

			public bool MoveNext()
			{
				int count = this.collectionRef.Count;
				bool flag = this.currentIndex + 1 < count && count == this.currentSize;
				if (flag)
				{
					this.currentIndex++;
					this.currentObject = this.collectionRef[this.currentIndex];
				}
				else
				{
					this.currentObject = null;
				}
				return flag;
			}

			public void Reset()
			{
				this.currentIndex = -1;
				this.currentObject = null;
				if (this.collectionRef.Count != this.currentSize)
				{
					throw new InvalidOperationException("Collection modified.");
				}
			}

			public void Dispose()
			{
				this.currentIndex = -1;
				this.currentObject = null;
			}

			private OdBoolArray collectionRef;

			private int currentIndex;

			private object currentObject;

			private int currentSize;
		}
	}
}
